
{
	open Lexing
	open Parser
  
	exception ErreurLexicale of char * int
	let newline lexbuf =
		let pos = lexbuf.lex_curr_p in
		lexbuf.lex_curr_p <- 
		{ pos with pos_lnum = pos.pos_lnum + 1; pos_bol = pos.pos_cnum }
      
	let keywords = ["char",CHAR;"else",ELSE;"for",FOR;"if",IF;"int",INT;"return",RETURN;"sizeof",SIZEOF;"struct",STRUCT;"union",UNION;"void",VOID;"while",WHILE]
	let id_or_kwd s = try List.assoc s keywords with _ -> IDENT s

	let hexa_to_dec h =
		let hexa_to_int c =
			match c with
			| 'A' -> 10
			| 'B' -> 11
			| 'C' -> 12
			| 'D' -> 13
			| 'E' -> 14
			| 'F' -> 15
			| _ as x -> int_of_string (String.make 1 x)
		in
		let hexa = String.uppercase h in
		let a = String.get hexa 0 in
		let b = String.get hexa 1 in
		(16 * (hexa_to_int a) + (hexa_to_int b))
			
	let hexa_to_char hexa =
		char_of_int (hexa_to_dec hexa)

	let chaine_actuelle = ref ""	
}

let chiffre = ['0'-'9']
let alpha = ['a'-'z' 'A'-'Z']
let ident = (alpha | ['_']) (alpha | chiffre | ['_'])*
let espace = " "*
let hexadecimal = ['0'-'9' 'a'-'f' 'A'-'F'] ['0'-'9' 'a'-'f' 'A'-'F']

rule token = parse
	| [' ' '\t'] {token lexbuf}
	| "/*" { commentaire lexbuf}
	| "//" {commentaire_simple lexbuf}
	| '\n' {newline lexbuf; token lexbuf}
	| chiffre+ as i { Parser.CST (int_of_string i)}
	| "\'" { chaine_actuelle := ""; car lexbuf;
		if (String.length !chaine_actuelle > 1)
		then (raise (ErreurLexicale (' ' ,(lexbuf.lex_curr_p.pos_lnum))))
		else Parser.CAR(String.get !chaine_actuelle 0) }
	| "\"" { chaine_actuelle := ""; chaine lexbuf; Parser.CHAINE(!chaine_actuelle) }
	| ident as i { id_or_kwd i }
	| ';' { Parser.POINT_VIRGULE }
	| '(' { Parser.PARENTHESE_GAUCHE }
	| ')' { Parser.PARENTHESE_DROITE }
	| '{' { Parser.ACCOLADE_GAUCHE }
	| '}' { Parser.ACCOLADE_DROITE }
	| '[' { Parser.CROCHET_GAUCHE }
	| ']' { Parser.CROCHET_DROIT}
	| "->" { Parser.FLECHE }
	| '.' { Parser.POINT }
	| "||" { Parser.BARBARE }
	| "&&" { Parser.HEHE }
	| "==" { Parser.EGAL }
	| "!=" { Parser.DIFFERENT }
	| "<" { Parser.INFERIEUR }
	| "<=" { Parser.INFERIEUR_EQ }
	| ">" { Parser.SUPERIEUR }
	| ">=" { Parser.SUPERIEUR_EQ }
	| '=' { Parser.ASSIGNATION }
	| "++" { Parser.PLUS_PLUS }
	| "--" { Parser.MOINS_MOINS }
	| "+" { Parser.PLUS }
	| "-" { Parser.MOINS }
	| "*" { Parser.ETOILE }
	| "/" { Parser.DIV }
	| "%" { Parser.MODULO }
	| "!" { Parser.POINT_EXCLAMATION }
	| "&" { Parser.REFERENCE }
	| "," { Parser.VIRGULE }
	|eof { Parser.EOF }
	| _ as c { raise (ErreurLexicale (c,(lexbuf.lex_curr_p.pos_lnum))) }
and
commentaire_simple = parse
	| '\n' {newline lexbuf; token lexbuf;}
	| _ {commentaire_simple lexbuf;}
and
commentaire = parse
	| '\n' {newline lexbuf; commentaire lexbuf;}
	| "*/" {token lexbuf}
	| _ {commentaire lexbuf;}
and
chaine = parse
	| '\n' { raise (ErreurLexicale (' ' ,(lexbuf.lex_curr_p.pos_lnum))) }
	| "\\x" ( hexadecimal as hexa) { chaine_actuelle := !chaine_actuelle ^ (String.make 1 (hexa_to_char hexa)); chaine lexbuf }
	| "\\\'" { chaine_actuelle := !chaine_actuelle ^ "\'"; chaine lexbuf }
	| "\\\\" { chaine_actuelle := !chaine_actuelle ^ "\\"; chaine lexbuf }
	| "\\\"" { chaine_actuelle := !chaine_actuelle ^ "\""; chaine lexbuf }
	| "\"" { }
	| _ as c { chaine_actuelle := !chaine_actuelle ^ (String.make 1 c); car lexbuf }
and
car = parse
	| '\n' { raise (ErreurLexicale (' ' ,(lexbuf.lex_curr_p.pos_lnum))) }
	| "\\x" ( hexadecimal as hexa) { chaine_actuelle := !chaine_actuelle ^ (String.make 1 (hexa_to_char hexa)); car lexbuf }
	| "\\\'" { chaine_actuelle := !chaine_actuelle ^ "\'"; car lexbuf }
	| "\\\\" { chaine_actuelle := !chaine_actuelle ^ "\\"; car lexbuf }
	| "\\\"" { chaine_actuelle := !chaine_actuelle ^ "\""; car lexbuf }
	| "\'" { }
	| _ as c { chaine_actuelle := !chaine_actuelle ^ (String.make 1 c); car lexbuf }








	
